#ifndef __FILE_TRANSFER__
#define __FILE_TRANSFER__

#include <sys/socket.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <errno.h>
#include <mysql/mysql.h>
#include "fileCheck.h"
#include "fileCommand.h"

// 支持超大文件传输
#define _FILE_OFFSET_BITS 64
// 大文件传输阈值
#define BIG_FILE_SIZE 100 * 1024 * 1024
// 文件分片大小
#define CHUNK_SIZE 4 * 1024
// 文件表的file_size更新阈值
#define CHUNK_UPDATE 4 * 1024 * 1024
// TLV 头字节数
#define TLV_HEAD_SIZE 5
// TLV 传输类型
#define TYPE_FILE_CHUNK 0x01 // 文件分片数据
#define TYPE_METADATA 0x02   // 文件元数据
#define TYPE_FLAG 0x03       // 校验标识
#define TYPE_FILE_CHECK 0x04 // 续传文件信息
#define TYPE_ABORT 0x1F      // 中止传输指令

// TLV 协议头实现（5字节）
typedef struct tlv_s
{
    int type;    // 传输类型
    int length; // 传输长度
} tlv_t;

// 手动实现 MSG_WAITALL
int recvn(int sockfd, void *buf, int n);

// 上传请求处理
int uploadHandle(int sockfd, MYSQL *mysql,  const filePath_t user_id);

// 下载请求处理
int downloadHandle(int sockfd, MYSQL *mysql, const char *file_path, const filePath_t user_id);

// 服务端发送数据
int serverSendData(int sockfd, int fd, fileCheck_t *file_check, int mmap_flag);

// 服务端接收数据
int serverRecvData(int sockfd, int fd, MYSQL *mysql, fileCheck_t *file_check, filePath_t user_id);

// 获取文件大小
int getLocalFileSize(const int fd, off_t *file_size);

// 需要的数据库接口
// int getFileSize(MYSQL *mysql, const char *file_name, const char *file_path, off_t *file_size);
// int getFileHash(MYSQL *mysql, const char *file_name, const char *file_path, char *file_hash);
// int checkFileExist(MYSQL *mysql, const char *file_name, const char *file_path);
// int isFileResume(MYSQL *mysql, const char *sha256);
// int insertFileSkip(MYSQL *mysql, const char *file_name, const char *sha256); // 秒传，跳过传输，直接插入一条记录即可
// int insertFileNew(MYSQL *mysql, const fileCheck_t *file_check);
// int updateFileInfo(MYSQL *mysql, off_t offset, const char *sha256, int flag);
// int deleteFile(MYSQL *mysql, const char *file_name, const char *file_path);
#endif
